<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 5.4.&nbsp; Buffering</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch05lev1sec3.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch05lev1sec5.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="top"><a name="ch05lev1sec4"></a>
<h3 class="docSection1Title" id="454331-878">5.4. Buffering</h3>
<p class="docText">The goal of the buffering provided by the standard I/O library is to use the minimum number of <tt>read</tt> and <tt>write</tt> calls. (Recall <a class="docLink" href="ch03lev1sec9.html#ch03fig05">Figure 3.5</a>, where we showed the amount of CPU time required to perform I/O using various buffer sizes.) Also, it tries to do its buffering automatically for each I/O stream, obviating the need for the application to worry about it. Unfortunately, the single aspect of the standard I/O library that generates the most confusion is its buffering.</P>
<p class="docText">Three types of buffering are provided:</P>
<div style="font-weight:bold"><ol class="docList" type="1"><li><div style="font-weight:normal"><p class="docList">Fully buffered. In this case, actual I/O takes place when the standard I/O buffer is filled. Files residing on disk are normally fully buffered by the standard I/O library. The buffer used is usually obtained by one of the standard I/O functions calling <tt>malloc</tt> (<a class="docLink" href="ch07lev1sec8.html#ch07lev1sec8">Section 7.8</a>) the first time I/O is performed on a stream.</P><p class="docList">The term <span class="docEmphasis">flush</span> describes the writing of a standard I/O buffer. A buffer can be flushed automatically by the standard I/O routines, such as when a buffer fills, or we can call the function <tt>fflush</tt> to flush a stream. Unfortunately, in the UNIX environment, <span class="docEmphasis">flush</span> means two different things. In terms of the standard I/O library, it means writing out the contents of a buffer, which may be partially filled. In terms of the terminal driver, such as the <tt>tcflush</tt> function in <a class="docLink" href="ch18.html#ch18">Chapter 18</a>, it means to discard the data that's already stored in a buffer.</P></div></LI><li><div style="font-weight:normal"><p class="docList">Line buffered. In this case, the standard I/O library performs I/O when a newline character is encountered on input or output. This allows us to output a single character at a time (with the standard I/O <tt>fputc</tt> function), knowing that actual I/O will take place only when we finish writing each line. Line buffering is typically used on a stream when it refers to a terminal: standard input and standard output, for example.</P><p class="docList">Line buffering comes with two caveats. First, the size of the buffer that the standard I/O library is using to collect each line is fixed, so I/O might take place if we fill this buffer before writing a newline. Second, whenever input is requested through the standard I/O library from either (a) an unbuffered stream <a name="idd1e35259"></a><a name="idd1e35264"></a><a name="idd1e35269"></a><a name="idd1e35274"></a><a name="idd1e35281"></a><a name="idd1e35286"></a>or (b) a line-buffered stream (that requires data to be requested from the kernel), <span class="docEmphasis">all</span> line-buffered output streams are flushed. The reason for the qualifier on (b) is that the requested data may already be in the buffer, which doesn't require data to be read from the kernel. Obviously, any input from an unbuffered stream, item (a), requires data to be obtained from the kernel.</P></div></LI><li><div style="font-weight:normal"><p class="docList">Unbuffered. The standard I/O library does not buffer the characters. If we write 15 characters with the standard I/O <tt>fputs</tt> function, for example, we expect these 15 characters to be output as soon as possible, probably with the <tt>write</tt> function from <a class="docLink" href="ch03lev1sec8.html#ch03lev1sec8">Section 3.8</a>.</P><p class="docList">The standard error stream, for example, is normally unbuffered. This is so that any error messages are displayed as quickly as possible, regardless of whether they contain a newline.</p></div></LI></ol></div>
<p class="docText">ISO C requires the following buffering characteristics.</P>
<UL><li><p class="docList">Standard input and standard output are fully buffered, if and only if they do not refer to an interactive device.</P></LI><li><p class="docList">Standard error is never fully buffered.</P></LI></ul>
<p class="docText">This, however, doesn't tell us whether standard input and standard output can be unbuffered or line buffered if they refer to an interactive device and whether standard error should be unbuffered or line buffered. Most implementations default to the following types of buffering.</p>
<ul><li><p class="docList">Standard error is always unbuffered.</P></li><LI><p class="docList">All other streams are line buffered if they refer to a terminal device; otherwise, they are fully buffered.</p><blockquote><P><p class="docList">The four platforms discussed in this book follow these conventions for standard I/O buffering: standard error is unbuffered, streams open to terminal devices are line buffered, and all other streams are fully buffered.</p></p></blockquote></li></ul>
<p class="docText">We explore standard I/O buffering in more detail in <a class="docLink" href="ch05lev1sec12.html#ch05lev1sec12">Section 5.12</a> and <a class="docLink" href="ch05lev1sec12.html#ch05fig11">Figure 5.11</a>.</p>
<p class="docText">If we don't like these defaults for any given stream, we can change the buffering by calling either of the following two functions.</p>
<a name="inta284"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="none" cellpadding="5"><colgroup><col width="500"></colgroup><thead></thead><tr><td class="docTableCell" align="left" valign="top"><p class="docText">
<a name="PLID0"></a><div class="v1"><a href="ch05lev1sec4.html#PLID0">[View full width]</a></div><pre>
#include &lt;stdio.h&gt;

void setbuf(FILE *restrict <span class="docEmphItalicAlt">fp</span>, char *restrict <span class="docEmphItalicAlt">buf</span>);

int setvbuf(FILE *restrict <span class="docEmphItalicAlt">fp</span>, char *restrict <span class="docEmphItalicAlt">buf</span>,
<img border="0" width="14" height="9" alt="" align="left" src="images/ccc.gif"> int <span class="docEmphItalicAlt">mode</span>,
            <span class="docEmphItalicAlt">size_t size</span>);
</pre><br>

</p></td></tr><tr><td class="docTableCell" align="right" valign="top"><p class="docText">Returns: 0 if OK, nonzero on error</p></td></TR></table></P><br>
<p class="docText">These functions must be called <span class="docEmphasis">after</span> the stream has been opened (obviously, since each requires a valid file pointer as its first argument) but <span class="docEmphasis">before</span> any other operation is performed on the stream.</P>
<p class="docText"><a name="idd1e35428"></a><a name="idd1e35433"></a><a name="idd1e35438"></a><a name="idd1e35445"></a><a name="idd1e35450"></a><a name="idd1e35455"></a><a name="idd1e35460"></a><a name="idd1e35465"></a>With <tt>setbuf</tt>, we can turn buffering on or off. To enable buffering, <span class="docEmphasis">buf</span> must point to a buffer of length <tt>BUFSIZ</tt>, a constant defined in <tt>&lt;stdio.h&gt;</tt>. Normally, the stream is then fully buffered, but some systems may set line buffering if the stream is associated with a terminal device. To disable buffering, we set <span class="docEmphasis">buf</span> to <tt>NULL</tt>.</P>
<p class="docText">With <tt>setvbuf</tt>, we specify exactly which type of buffering we want. This is done with the <span class="docEmphasis">mode</span> argument:</P>
<p><table cellspacing="0" FRAME="void" RULES="none" cellpadding="5"><colgroup><col width="100"><col width="100"></colgroup><thead></thead><TR><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>_IOFBF</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText">fully buffered</p></TD></TR><TR><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>_IOLBF</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText">line buffered</P></TD></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>_IONBF</tt></p></TD><td class="docTableCell" align="left" valign="top"><p class="docText">unbuffered</P></td></TR></table></p><br>
<p class="docText">If we specify an unbuffered stream, the <span class="docEmphasis">buf</span> and <span class="docEmphasis">size</span> arguments are ignored. If we specify fully buffered or line buffered, <span class="docEmphasis">buf</span> and <span class="docEmphasis">size</span> can optionally specify a buffer and its size. If the stream is buffered and <span class="docEmphasis">buf</span> is <tt>NULL</tt>, the standard I/O library will automatically allocate its own buffer of the appropriate size for the stream. By appropriate size, we mean the value specified by the constant <tt>BUFSIZ</tt>.</p>
<blockquote>
<p class="docText">Some C library implementations use the value from the <tt>st_blksize</tt> member of the <tt>stat</tt> structure (see <a class="docLink" href="ch04lev1sec2.html#ch04lev1sec2">Section 4.2</a>) to determine the optimal standard I/O buffer size. As we will see later in this chapter, the GNU C library uses this method.</p>
</blockquote>
<p class="docText"><a class="docLink" href="#ch05fig01">Figure 5.1</a> summarizes the actions of these two functions and their various options.</p>
<a name="ch05fig01"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="all" cellpadding="4"><caption><h5 class="docTableTitle">Figure 5.1. Summary of the <tt>setbuf</tt> and <tt>setvbuf</tt> functions</h5></caption><colgroup><col width="50"><col width="50"><col width="50"><col width="200"><col width="150"></colgroup><thead><tr><th class="thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman">Function</span></p></th><th class="thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman"><span class="docEmphasis">mode</span></span></p></th><th class="thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman"><span class="docEmphasis">buf</span></span></p></th><th class="thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman">Buffer and length</span></p></th><th class="thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman">Type of buffering</span></p></th></tr></thead><tr><td class="docTableCell" align="left" valign="middle" rowspan="2"><p class="docText"><tt>setbuf</tt></P></TD><td class="docTableCell" align="left" valign="middle" rowspan="2">&nbsp;</TD><TD class="docTableCell" align="left" valign="top"><p class="docText">non-null</P></td><TD class="docTableCell" align="left" valign="top"><p class="docText">user <span class="docEmphasis">buf</span> of length <tt>BUFSIZ</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText">fully buffered or line buffered</P></td></TR><TR><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>NULL</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText">(no buffer)</p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText">unbuffered</p></td></tr><tr><TD class="docTableCell" align="left" valign="middle" rowspan="5"><p class="docText"><tt>setvbuf</tt></p></TD><td class="docTableCell" align="left" valign="middle" rowspan="2"><p class="docText"><tt>_IOLBF</tt></P></td><td class="docTableCell" align="left" valign="top"><p class="docText">non-null</p></td><td class="docTableCell" align="left" valign="top"><p class="docText">user <span class="docEmphasis">buf</span> of length <span class="docEmphasis">size</span></p></td><td class="docTableCell" align="left" valign="middle" rowspan="2"><p class="docText">fully buffered</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>NULL</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText">system buffer of appropriate length</p></TD></TR><tr><TD class="docTableCell" align="left" valign="middle" rowspan="2"><p class="docText"><tt>_IOFBF</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText">non-null</P></TD><TD class="docTableCell" align="left" valign="top"><p class="docText">user <span class="docEmphasis">buf</span> of length <span class="docEmphasis">size</span></p></TD><td class="docTableCell" align="left" valign="middle" rowspan="2"><p class="docText">line buffered</P></TD></TR><tr><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>NULL</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText">system buffer of appropriate length</P></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>_IONBF</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText">(ignored)</p></TD><td class="docTableCell" align="left" valign="top"><p class="docText">(no buffer)</p></td><td class="docTableCell" align="left" valign="top"><p class="docText">unbuffered</p></td></tr></table></p><br>
<p class="docText">Be aware that if we allocate a standard I/O buffer as an automatic variable within a function, we have to close the stream before returning from the function. (We'll discuss this more in <a class="docLink" href="ch07lev1sec8.html#ch07lev1sec8">Section 7.8</a>.) Also, some implementations use part of the buffer for internal bookkeeping, so the actual number of bytes of data that can be stored in the buffer is less than <span class="docEmphasis">size</span>. In general, we should let the system choose the buffer size and automatically allocate the buffer. When we do this, the standard I/O library automatically releases the buffer when we close the stream.</p>
<p class="docText">At any time, we can force a stream to be flushed.</p>
<a name="inta61"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="none" cellpadding="5"><colgroup><col width="500"></colgroup><thead></thead><tr><td class="docTableCell" align="left" valign="top"><p class="docText">
<pre>
#include &lt;stdio.h&gt;

int fflush(FILE *<span class="docEmphItalicAlt">fp</span>);
</pre><br>

</p></td></TR><TR><td class="docTableCell" align="right" valign="top"><p class="docText">Returns: 0 if OK, <tt>EOF</tt> on error</P></TD></TR></table></p><BR>
<p class="docText">This function causes any unwritten data for the stream to be passed to the kernel. As a special case, if <span class="docEmphasis">fp</span> is <tt>NULL</tt>, this function causes all output streams to be flushed.</P>

<UL></ul></TD></tr></table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch05lev1sec3.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch05lev1sec5.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
</body></html><br>
<table width="100%" cellspacing="0" cellpadding="0"
style="margin-top: 0pt; border-collapse: collapse;"> 
<tr> <td align="right" style="background-color=white; border-top: 1px solid gray;"> 
<a href="http://www.zipghost.com/" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">The CHM file was converted to HTM by Trial version of <b>ChmD<!--239-->ecompiler</b>.</a>
</TD>
</TR><tr>
<td align="right" style="background-color=white; "> 
<a href="http://www.etextwizard.com/download/cd/cdsetup.exe" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">Download <b>ChmDec<!--239-->ompiler</b> at: http://www.zipghost.com</a>
</TD></tr></table>
